#include <nice2d/application.h>
#include <nice2d/background.h>
#include <nice2d/widgets/desktop.h>
#include <nice2d/widgets/titlebar.h>
#include <nice2d/widgets/basicbutton.h>
#include <nice2d/components/imagemanager.h>

IMPLEMENT_OBJECT(TitleBarStyle, LayoutStyle)

TitleBarStyle::TitleBarStyle()
{
    normalBackground = Background::create(sf::Color(128, 128, 128, 240));
    hoverBackground = Background::create(sf::Color(150, 150, 150, 240));
    pressedBackground = Background::create(sf::Color(180, 180, 180, 240));

    titleStyle = std::make_shared<LabelStyle>();
    titleStyle->textColor = sf::Color::Black;
    titleStyle->normalBackground = Background::create(sf::Color::Transparent);
    titleStyle->hoverBackground = titleStyle->normalBackground;
    titleStyle->pressedBackground = titleStyle->normalBackground;

    auto imageManager = GET_APPLICATION_COMPONENT(ImageManager);

    closeButtonStyle = std::make_shared<ControlStyle>();
    closeButtonStyle->normalBackground = Background::create("./../data/theme/BabyBlue.png", true, {96, 2, 25, 25});
    closeButtonStyle->hoverBackground = Background::create("./../data/theme/BabyBlue.png", true, {123, 2, 25, 25});
    closeButtonStyle->pressedBackground = closeButtonStyle->normalBackground;
}

TitleBarStyle::~TitleBarStyle()
{
}

class TitleBarData
{
public:
    TitleBar *titleBar = nullptr;
    std::shared_ptr<DraggableLabel> title;
    std::shared_ptr<BasicButton> closeButton;

    TitleBarData(TitleBar *thisTitleBar):
        titleBar(thisTitleBar)
    {
        auto desktop = GET_APPLICATION_COMPONENT(Desktop);
        auto style = std::dynamic_pointer_cast<TitleBarStyle>(desktop->getControlStyle("TitleBar"));
        titleBar->setControlStyle(style);
        titleBar->setHResizeRule(ControlResizeRule_Fill);
        titleBar->setVResizeRule(ControlResizeRule_Fixed);
    }

    void clickedCloseButton()
    {
        titleBar->closeButtonPressed();
    }
};

IMPLEMENT_OBJECT(TitleBar, HBoxLayout)

std::shared_ptr<TitleBar> TitleBar::create(const sf::String &title)
{
    auto titleBar = std::make_shared<TitleBar>();
    titleBar->data->title = std::make_shared<DraggableLabel>();
    titleBar->data->title->setHResizeRule(ControlResizeRule_Fill);
    titleBar->data->title->setText(title);
    titleBar->data->closeButton = std::make_shared<BasicButton>();
    titleBar->data->closeButton->setSize(28, 28);
    titleBar->data->closeButton->setHResizeRule(ControlResizeRule_Fixed);
    titleBar->addWidget(titleBar->data->title);
    titleBar->addWidget(titleBar->data->closeButton);

    titleBar->data->closeButton->pressed.connect(std::bind(&TitleBarData::clickedCloseButton,
                                                           titleBar->data.get()));

    auto style = std::dynamic_pointer_cast<TitleBarStyle>(titleBar->getControlStyle());
    titleBar->data->title->setControlStyle(style->titleStyle);
    titleBar->data->closeButton->setControlStyle(style->closeButtonStyle);

    return titleBar;
}

TitleBar::TitleBar():
    data(new TitleBarData(this))
{
}

TitleBar::~TitleBar()
{
}

void TitleBar::setTitle(const sf::String &title)
{
    data->title->setText(title);
}

sf::String TitleBar::getTitle() const
{
    return data->title->getText();
}

void TitleBar::setDraggableTarget(ControlPointer target)
{
    data->title->setTargetControl(target);
}

void TitleBar::adjust()
{
    float width = getWidth();
    width = width - data->closeButton->getWidth() - 2.0f * getMargin() - getSpacing();
    if (width > 10.0f)
        data->title->setWidth(width);
    HBoxLayout::adjust();
}

void TitleBar::onStyleChanged()
{
    Control::onStyleChanged();
    auto style = getTemplateStyle<TitleBarStyle>();
    data->title->setControlStyle(style->titleStyle);
    data->closeButton->setControlStyle(style->closeButtonStyle);
}

void TitleBar::onMouseEnter()
{
    if (isActive()) {
        auto style = getControlStyle();
        setBackground(style->hoverBackground);
    }

    Control::onMouseEnter();
}

void TitleBar::onMouseExit()
{
    if (isActive()) {
        auto style = getControlStyle();
        setBackground(style->normalBackground);
    }

    Control::onMouseExit();
}

void TitleBar::onMousePressed(sf::Mouse::Button button)
{
    if (isActive() && button == sf::Mouse::Button::Left) {
        auto style = getControlStyle();
        setBackground(style->pressedBackground);
    }
}

void TitleBar::onMouseReleased(sf::Mouse::Button button)
{
    if (isActive() && button == sf::Mouse::Button::Left) {
        auto style = getControlStyle();
        setBackground(style->hoverBackground);
    }
}
